#include <cstdint>
#include <memory>
#include <mio/mmap.hpp>
#include <optional>
#include <shared_mutex>
#include <string_view>
#include <vector>
#include <iostream>
#include <fstream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

namespace wal {

typedef std::string_view str;
enum RecordType {
  RecordTypeZero,
  RecordTypeFull,
  RecordTypeFirst,
  RecordTypeMiddle,
  RecordTypeLast
};

static constexpr int recordHeaderSize = 7; // 1字节类型 + 2字节长度 + 4字节CRC
static constexpr int maxPayloadSize = 32 * 1024; // 32KB
static constexpr int recordSize = recordHeaderSize + maxPayloadSize;

typedef uint8_t byte;
typedef std::vector<byte> bytes;
class SharedMutexWrapper {
public:
  std::shared_mutex mtx;
};
class WAL {
private:
  mio::mmap_sink mmap;
  std::shared_ptr<SharedMutexWrapper> mu;
  bytes record;
	std::string filename;
	size_t file_size;

public:
  WAL(std::string _filename)
      : mu(std::make_shared<SharedMutexWrapper>()), record(recordSize),
        file_size(0), filename(_filename) {
		// Create empty file if it doesn't exist
    std::ofstream file(filename, std::ios::binary | std::ios::app);
    file.close();

    std::error_code error;
    mmap = mio::make_mmap_sink(filename, 0, mio::map_entire_file, error);
    if (error) {
      throw std::runtime_error("Failed to create memory mapping: " + error.message());
    }
    file_size = mmap.size();
  }

  ~WAL() {
    std::error_code error;
		mmap.sync(error);
		mmap.unmap();
	}

  class WalIterator {
  private:
    mio::mmap_source mmap;
    std::shared_ptr<SharedMutexWrapper> mu;
    int64_t offset{};
    bytes record;

  public:
    WalIterator(const std::string& filename,
                std::shared_ptr<SharedMutexWrapper> mu)
        : record() {
			      std::error_code error;
      mmap = mio::make_mmap_source(filename, error);
      if (error) {
        throw std::runtime_error("Failed to create read mapping: " + error.message());
      }
    }

    std::optional<bytes> next();
  };
  void write(const bytes &data);

  void sync();
  // Other methods like NewIterator, Close, etc.

  WalIterator iter();
};
} // namespace wal
